home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C++ / Applications / Nuntius 1.2 / src / Nuntius / UArticleStatus.cp < prev    next >
Encoding:
Text File  |  1994-02-20  |  8.6 KB  |  364 lines  |  [TEXT/MPS ]

  1. // Copyright © 1992 Peter Speck, speck@dat.ruc.dk. All rights reserved.
  2. // UArticleStatus.cp
  3.  
  4. #include "UArticleStatus.h"
  5. #include "Tools.h"
  6. #include "UPrefsDatabase.h"
  7. #include "StreamTools.h"
  8.  
  9. #include <RsrcGlobals.h>
  10.  
  11. #pragma segment MyArticle
  12.  
  13. #define qDebugSpecify qDebug & 0
  14. #define qDebugStatusChanges qDebug & 0
  15.  
  16. const long kCurrentASVersion = 2;
  17. const long kMinASVersion = 2;
  18.  
  19. TArticleStatus::TArticleStatus()
  20. {
  21. }
  22.  
  23. pascal void TArticleStatus::Initialize()
  24. {
  25.     inherited::Initialize();
  26.     fFirstID = 0;
  27.     fChanged = false;
  28.     fDoc = nil;
  29. }
  30.  
  31. void TArticleStatus::IArticleStatus(TDocument *doc)
  32. {
  33.     inherited::ILongintList();
  34.     fDoc = doc;
  35. }
  36.  
  37. pascal void TArticleStatus::Free()
  38. {
  39. #if qDebugSpecify
  40.     fprintf(stderr, "Before TArticleStatus::Free():\n");
  41.     DebugDump();
  42. #endif
  43.     inherited::Free();
  44. }
  45.  
  46. void TArticleStatus::SpecifyWithArticleStatus(TArticleStatus *articleStatus)
  47. {
  48.     long size = articleStatus->GetSize();
  49.     SetArraySize(size);
  50.     fSize = size;
  51.     fFirstID = articleStatus->fFirstID;
  52.     Ptr fromP = articleStatus->ComputeAddress(1);
  53.     Ptr toP = ComputeAddress(1);
  54.     BytesMove(fromP, toP, size * sizeof(long));
  55.     fChanged = articleStatus->fChanged;
  56. }
  57.  
  58. void TArticleStatus::DoIronAgeFormatRead(TStream *aStream)
  59. {
  60.     aStream->ReadLong(); // size of info
  61.     fFirstID = aStream->ReadLong();
  62.     long size = aStream->ReadLong();
  63.  
  64.     SetArraySize(size);
  65.     fSize = size;
  66.     if (fSize) 
  67.     {
  68.         Boolean prevLock = Lock(true);
  69.         aStream->ReadBytes(ComputeAddress(1), fSize * sizeof(long));
  70.         Lock(prevLock);
  71.     }
  72.     fChanged = false;
  73. #if qDebugSpecify
  74.     fprintf(stderr, "After TArticleStatus::DoIronAgeFormatRead():\n");
  75.     DebugDump();
  76. #endif
  77. }
  78.  
  79. void TArticleStatus::DoRead(TStream *aStream)
  80. {
  81.     long version = aStream->ReadLong();
  82.     MyStreamCheckVersion(version, kMinASVersion, kCurrentASVersion, "TArticleStatus");
  83.     fFirstID = aStream->ReadLong();
  84.     ReadDynamicArray(aStream, this);
  85.     fChanged = false;
  86. #if qDebugSpecify
  87.     fprintf(stderr, "After TArticleStatus::DoRead():\n");
  88.     DebugDump();
  89. #endif
  90. }
  91.  
  92. void TArticleStatus::DoWrite(TStream *aStream)
  93. {
  94.     aStream->WriteLong(kCurrentASVersion);
  95.     aStream->WriteLong(fFirstID);
  96.     WriteDynamicArray(aStream, this);
  97.     fChanged = false;
  98. }
  99.  
  100. void TArticleStatus::DoNeedDiskSpace(long &dataForkBytes)
  101. {
  102.     dataForkBytes += sizeof(long); // version
  103.     dataForkBytes += sizeof(long); // fFirstID
  104.     dataForkBytes += MyStreamSizeOfDynamicArray(this);
  105. }
  106.  
  107. void TArticleStatus::IsChanged()
  108. {
  109.     if (fChanged)
  110.         return;
  111.     fChanged = true;
  112. #if qDebug
  113.     if (!fDoc)
  114.         return; // TestCode
  115. #endif
  116.     fDoc->Changed(cArticleStatusChange, this);
  117. #if qDebugStatusChanges
  118.     fprintf(stderr, "TArticleStatus::IsChanged():  Changed() document\n");
  119. #endif
  120. }
  121.  
  122. ArticleStatus TArticleStatus::GetStatus(long id)
  123. {
  124.     long index = id - fFirstID + 1;
  125.     if (index < 1)
  126.         return kArticleSeen; // I think
  127.     if (index > fSize)
  128.         return kArticleNew;
  129. #if qDebugStatusChanges
  130.     fprintf(stderr, "TArticleStatus::GetStatus(%ld) == %ld\n", id, At(index));
  131. #endif
  132.     return ArticleStatus(At(index));
  133. }
  134.  
  135. void TArticleStatus::SetStatus(long id, ArticleStatus status)
  136. {
  137.     long index = id - fFirstID + 1;
  138. #if qDebugStatusChanges
  139.     fprintf(stderr, "TArticleStatus::SetStatus(id = %ld, stat = %ld), index = %ld, fSize = %ld\n",
  140.       id, long(status), index, fSize);
  141. #endif
  142.     if (index < 1 || index > fSize)
  143.     {
  144. #if qDebug
  145.         fprintf(stderr, "TArticleStatus::SetStatus, id = %ld, fFirstID = %ld lastID = %ld\n", id, fFirstID, fFirstID+fSize-1);
  146. #endif
  147.         return;
  148.     }
  149.     if (At(index) == status)
  150.         return;
  151. #if qDebugStatusChanges
  152.     fprintf(stderr, "-   Changed from %ld\n", At(index));
  153. #endif
  154.     AtPut(index, status);
  155.     IsChanged();
  156. }
  157.  
  158. void TArticleStatus::SetMinStatus(long id, ArticleStatus status)
  159. {
  160.     long index = id - fFirstID + 1;
  161. #if qDebugStatusChanges
  162.     fprintf(stderr, "TArticleStatus::SetMinStatus(id = %ld, stat = %ld), index = %ld, fSize = %ld\n",
  163.       id, long(status), index, fSize);
  164. #endif
  165.     if (index < 1 || index > fSize)
  166.     {
  167. #if qDebug
  168.         fprintf(stderr, "TArticleStatus::SetMinStatus, id = %ld, fFirstID = %ld lastID = %ld\n", id, fFirstID, fFirstID+fSize-1);
  169. #endif
  170.         return;
  171.     }
  172.     if (At(index) >= status)
  173.         return;
  174. #if qDebugStatusChanges
  175.     fprintf(stderr, "-   Changed from %ld\n", At(index));
  176. #endif
  177.     AtPut(index, status);
  178.     IsChanged();
  179. }
  180.  
  181. void TArticleStatus::SetNewRange(long newFirstID, long newLastID)
  182. {
  183.     if (newLastID < newFirstID)
  184.     {
  185.         // empty groups, delete everything
  186.         if (fSize)
  187.             IsChanged();
  188.         fFirstID = 0;
  189.         DeleteAll();
  190.         return;
  191.     }
  192. #if qDebug
  193.     if (newLastID > newFirstID + 10000)
  194.         ProgramBreak("newLastID > newFirstID + 10000");
  195. #endif
  196.     long lastID = fFirstID + fSize - 1;
  197.     if (newFirstID == fFirstID && newLastID == lastID)
  198.         return; // no change in range
  199.     long newSize = newLastID - newFirstID + 1;
  200. #if qDebugSpecify
  201.     fprintf(stderr, "TArticleStatus::SetNewRangle, newFirstID = %ld, newLastID = %ld, newSize = %ld\n", newFirstID, newLastID, newSize);
  202.     fprintf(stderr, "-                fFirstID = %ld, fSize = %ld, fLastID = %ld\n", fFirstID, fSize, fFirstID + fSize - 1);
  203. #endif
  204.     IsChanged();
  205.     if (newLastID < fFirstID || newFirstID > lastID)
  206.     {
  207. #if qDebugSpecify
  208.         fprintf(stderr, "-      Deletes all old stuff, initializes whole array with kArticleNew\n");
  209. #endif
  210.         SetArraySize(newSize);
  211.         fSize = newSize;
  212.         long *lP = (long*)ComputeAddress(1);
  213.         for (long i = 1; i <= newSize; i++)
  214.             *lP++ = kArticleNew;
  215.         fFirstID = newFirstID;
  216.         return;
  217.     }
  218.     if (newSize > fSize)
  219.     {
  220. #if qDebugSpecify
  221.         fprintf(stderr, "-    Extending allocated array size to %ld\n", newSize);
  222. #endif
  223.         SetArraySize(newSize);
  224.         fSize = newSize;
  225.     }
  226.     long commonFirstID = Max(fFirstID, newFirstID);
  227.     long commonLastID = Min(lastID, newLastID);
  228. #if qDebugSpecify
  229.     fprintf(stderr, "-    commonFirstID = %ld, commonLastID = %ld\n", commonFirstID, commonLastID);
  230. #endif
  231.     if (newFirstID != fFirstID)
  232.     {
  233.         Ptr fromP = ComputeAddress(commonFirstID - fFirstID + 1);
  234.         Ptr toP = ComputeAddress(commonFirstID - newFirstID + 1);
  235.         long size = commonLastID - commonFirstID + 1;
  236.         MyBlockMove(fromP, toP, size * sizeof(long));
  237.         if (newFirstID < commonFirstID)
  238.         {
  239.             long no = commonFirstID - newFirstID;
  240.             long *lP = (long*)ComputeAddress(1);
  241.             for (long i = 1; i <= no; i++)
  242.                 *lP++ = kArticleNew;
  243.         }
  244. #if qDebugSpecify
  245.     fprintf(stderr, "-    moved %ld articles from $%lx to $%lx\n", size, fromP, toP);
  246. #endif
  247.     }
  248.     if (newSize < fSize)
  249.     {
  250. #if qDebugSpecify
  251.         fprintf(stderr, "-    Decreasing allocated array size to %ld\n", newSize);
  252. #endif
  253.         SetArraySize(newSize);
  254.         fSize = newSize;
  255.     }
  256.     fFirstID = newFirstID;
  257.     if (newLastID > commonLastID)
  258.     {
  259.         long no = newLastID - commonLastID;
  260.         long firstNewID = commonLastID + 1;
  261.         long *lP = (long*)ComputeAddress(firstNewID - newFirstID + 1);
  262.         for (long i = 1; i <= no; i++)
  263.             *lP++ = kArticleNew;
  264. #if qDebugSpecify
  265.         fprintf(stderr, "-    added %ld new articles with status = kArticleNew\n", no);
  266. #endif
  267.     }
  268. #if qDebugSpecify
  269.     fprintf(stderr, "After TArticleStatus::SetNewRange():\n");
  270.     DebugDump();
  271. #endif
  272. }
  273.  
  274. void TArticleStatus::DebugDump()
  275. {
  276. #if qDebug
  277.     fprintf(stderr, "DebugDump of TArticleStatus:\n");
  278.     for (ArrayIndex index = 1; index <= fSize; index++)
  279.     {
  280.         long id = fFirstID + index - 1;
  281.         if (id % 10 == 0 || index == 1)
  282.             fprintf(stderr, "%4ld: ", id);
  283.         long value = At(index);
  284.         fprintf(stderr, "%3ld", value);
  285.         if ((id + 1) % 10 == 0)
  286.             fprintf(stderr, "\n");
  287.     }
  288.     fprintf(stderr, "\nEnd of dump\n");
  289. #endif
  290. }
  291.  
  292. Boolean TArticleStatus::SanityCheck()
  293. {
  294.     Boolean isGood = true;
  295. #if qDebug
  296.     for (ArrayIndex index = 1; index <= fSize; index++)
  297.     {
  298.         long stat = At(index);
  299.         if (stat < 0 || stat > kArticleRead)
  300.         {
  301.             fprintf(stderr, "Wrong: TArticleStatus::SanityCheck, bad value %ld with index %ld\n", stat, index);
  302.             isGood = false;
  303.         }
  304.     }
  305.     if (!isGood)
  306.     {
  307.         DebugDump();
  308.         ProgramBreak("TArticleStatus was BAD!");
  309.     }
  310. #endif
  311.     return isGood;
  312. }
  313.  
  314.  
  315. #if 0
  316. void Test1()
  317. {
  318. #if qDebug
  319.     TArticleStatus *stat = new TArticleStatus();
  320.     stat->IArticleStatus(nil);
  321.     
  322.     fprintf(stderr, "After init:\n");
  323.     stat->SanityCheck();
  324.     stat->DebugDump();
  325.     
  326.     fprintf(stderr, "After NewRange 10-20\n");
  327.     stat->SetNewRange(10, 20);
  328.     stat->SanityCheck();
  329.     stat->DebugDump();
  330.     
  331.     ArrayIndex id;
  332.     for (id = 10; id <= 20; id++)
  333.         stat->SetStatus(id, ArticleStatus(id - 10));
  334.     fprintf(stderr, "After Fill of 10-20\n");
  335.     stat->SanityCheck();
  336.     stat->DebugDump();
  337.  
  338.     stat->SetNewRange(13, 24);
  339.     fprintf(stderr, "After NewRange 13-24:\n");
  340.     stat->SanityCheck();
  341.     stat->DebugDump();
  342.     
  343.     for (id = 21; id <= 24; id++)
  344.         stat->SetStatus(id, ArticleStatus(id - 10));
  345.     fprintf(stderr, "After fill range 21-25\n");
  346.     stat->SanityCheck();
  347.     stat->DebugDump();
  348.  
  349.     stat->SetNewRange(17, 29);
  350.     fprintf(stderr, "After new range 17-29\n");
  351.     stat->SanityCheck();
  352.     stat->DebugDump();
  353.     
  354.     for (id = 25; id <= 29; id++)
  355.         stat->SetStatus(id, ArticleStatus(id - 10));
  356.     fprintf(stderr, "After fill range 26-29:\n");
  357.     stat->SanityCheck();
  358.     stat->DebugDump();
  359.     
  360.     stat->Free(); stat = nil;
  361. #endif
  362. }
  363. #endif
  364.